package cqrtplm.aop;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import com.hustcad.plm.basic.dto.defaultvalue.TyplmDefaultValueDTO;
import com.hustcad.plm.basic.dto.defaultvalue.TyplmDefaultValueParamDTO;
import com.hustcad.plm.pdm.classification.model.dto.TyplmClassificationEntityDTO;
import com.hustcad.plm.pdm.classification.model.vo.TyplmClassificationVO;
import com.hustcad.plm.pdm.classification.service.TyplmClassificationCacheService;
import com.hustcad.plm.pdm.constraint.model.dto.TyplmConstraintQueryDTO;
import com.hustcad.plm.pdm.constraint.model.vo.TyplmConstraintEditVO;
import com.hustcad.plm.pdm.constraint.service.TyplmConstraintExtService;
import com.hustcad.plm.pdm.enumeration.model.vo.EnumerationItemHandleVO;
import com.hustcad.plm.pdm.enumeration.service.TyplmEnumerationItemService;
import com.hustcad.plm.pdm.iba.mapper.TyplmAttributeDefaultValueMapper;
import com.ty.basic.constant.TableTypeConstrant;
import com.ty.basic.entity.IdentifierEntity;
import com.ty.basic.entity.attribute.AttributeDefaultValueDO;
import cqrtplm.constant.RTErrorCodeEnum;
import cqrtplm.mapper.ProcessNumberMapper;
import cqrtplm.mapper.RTTypeClassMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.math.BigInteger;
import java.util.*;

@Aspect
@Component
@Slf4j
public class RTClassificationAOP {


    @Resource
    private ProcessNumberMapper processNumberMapper;
    @Resource
    private TyplmEnumerationItemService typlmEnumerationItemService;
    @Resource
    private RTTypeClassMapper rtTypeClassMapper;
    @Resource
    private TyplmAttributeDefaultValueMapper typlmAttributeDefaultValueMapper;

    @Around(value = "execution(* com.hustcad.plm.pdm.classification.service.TyplmClassificationService.insertClassification(..))")
    public Object createClassificationAop(ProceedingJoinPoint point) throws Throwable {
        Object[] args = point.getArgs();
        TyplmClassificationEntityDTO dto = (TyplmClassificationEntityDTO) args[0];
        if (StringUtils.isBlank(dto.getInternalName())) {
            String ibaAttrCode = processNumberMapper.generateClassificationInternalName();
            String displayName = dto.getDisplayName();
            if (displayName.contains("图样代号")) {
                dto.setInternalName("T_" + ibaAttrCode);
            } else if (displayName.contains("标准件")) {
                dto.setInternalName("B_" + ibaAttrCode);
            } else if (displayName.contains("物料码")) {
                dto.setInternalName("W_" + ibaAttrCode);
            } else if (displayName.contains("EBOM号")) {
                dto.setInternalName("L_" + ibaAttrCode);
            } else {
                dto.setInternalName(ibaAttrCode);
            }
        }
        int i = rtTypeClassMapper.checkClassDisplayNameIfExist(dto.getDisplayName());
        if (i != 0) {
            throw RTErrorCodeEnum.CLASSIFICATION_NOT_UNIQUE_ERROR.getException("分类名称已存在");
        }
        return point.proceed();
    }

    @Around(value = "execution(* com.hustcad.plm.pdm.classification.service.TyplmClassificationService.queryClassification(..))")
    public Object updateClassificationAop(ProceedingJoinPoint point) throws Throwable {
        List<TyplmClassificationEntityDTO> proceed = (List<TyplmClassificationEntityDTO>) point.proceed();
        if (proceed != null && !proceed.isEmpty()) {
            proceed.sort((dto1, dto2) -> {
                String code1 = dto1.getCode();
                String code2 = dto2.getCode();
                boolean isCode1Blank = StringUtils.isBlank(code1);
                boolean isCode2Blank = StringUtils.isBlank(code2);
                if (!isCode1Blank && !isCode2Blank) {
                    return code1.compareTo(code2);
                }
                if (!isCode1Blank) {
                    return -1;
                }
                if (!isCode2Blank) {
                    return 1;
                }
                String displayName1 = dto1.getDisplayName();
                String displayName2 = dto2.getDisplayName();
                if (displayName1 == null && displayName2 == null) {
                    return 0;
                }
                if (displayName1 == null) {
                    return 1;
                }
                if (displayName2 == null) {
                    return -1;
                }
                return displayName1.compareTo(displayName2);
            });
        }
        return proceed;
    }

    @Resource
    private TyplmConstraintExtService typlmConstraintExtService;

    @Before(value = "execution(* com.hustcad.plm.pdm.defaultvalue.TyplmDefaultValueService.createEntityDefaultValue(..))")
    public void updateClassificationAop(JoinPoint point) throws Throwable {
        Object[] args = point.getArgs();
        List<TyplmDefaultValueParamDTO> defaultValueDTOS = (List<TyplmDefaultValueParamDTO>) args[0];
        for (TyplmDefaultValueParamDTO dto : defaultValueDTOS) {
            IdentifierEntity entity = dto.getEntity();
            TyplmDefaultValueDTO defaultValueDTO = dto.getDefaultValue();
            String defaultValue = defaultValueDTO.getValue();
            if (StringUtils.isBlank(defaultValue)) {
                continue;
            }
            List<TyplmConstraintQueryDTO> constraintQueryDTOS = new ArrayList<>();
            TyplmConstraintQueryDTO typlmConstraintQueryDTO = new TyplmConstraintQueryDTO();
            typlmConstraintQueryDTO.setAttributereferenceoid(entity.getOid());
            typlmConstraintQueryDTO.setAttributereferenceotype(entity.getOtype());
            constraintQueryDTOS.add(typlmConstraintQueryDTO);
            List<TyplmConstraintEditVO> constraintEditVOS = this.typlmConstraintExtService.getEntityConstraint(
                    constraintQueryDTOS);
            for (TyplmConstraintEditVO typlmConstraintEditVO : constraintEditVOS) {
                String name = typlmConstraintEditVO.getName();
                if ("枚举值列表".equals(name) && "0".equals(typlmConstraintEditVO.getDisabled())) {
                    String enumOid = typlmConstraintEditVO.getEnumoid();
                    if (StringUtils.isBlank(enumOid)) {
                        return;
                    }
                    List<EnumerationItemHandleVO> enumItems = typlmEnumerationItemService.queryEnumerationItemByDefOid(
                            new IdentifierEntity(new BigInteger(enumOid), TableTypeConstrant.TY_ENUMERATIONDEF_OTYPE));
                    Map<String, String> enumMap = new HashMap<>();
                    for (EnumerationItemHandleVO enumerationItemHandleVO : enumItems) {
                        enumMap.put(enumerationItemHandleVO.getDisplayName(), enumerationItemHandleVO.getName());
                        enumMap.put(enumerationItemHandleVO.getName(), enumerationItemHandleVO.getName());
                    }
                    if (enumMap.containsKey(defaultValue)) {
                        defaultValueDTO.setValue(enumMap.get(defaultValue));
                    } else {
                        throw RTErrorCodeEnum.ENUM_VALUE_NOT_EXIST.getException(
                                "维护的默认值：" + defaultValue + "不在可选范围，请重新维护!");
                    }
                }
            }
        }
    }

    @Resource
    private TyplmAttributeDefaultValueMapper attributeDefaultValueMapper;

    @Resource
    private TyplmClassificationCacheService typlmClassificationCacheService;

    @Before(value = "execution(* com.hustcad.plm.pdm.iba.service.impl.TyplmAttributeDefaultValueServiceImpl.deleteAttributeDefaultValue(..))")
    public void deleteAttributeDefaultValue(JoinPoint point) throws Throwable {
        Object[] args = point.getArgs();
        BigInteger oid = (BigInteger) args[0];
        Example example = new Example(AttributeDefaultValueDO.class, true, true);
        example.createCriteria().andEqualTo("oid", oid);
        List<AttributeDefaultValueDO> attributeDefaultValueDOS = attributeDefaultValueMapper.selectByExample(example);
        for (AttributeDefaultValueDO attributeDefaultValueDO : attributeDefaultValueDOS) {
            BigInteger attributereferenceOid = attributeDefaultValueDO.getContextreferenceoid();
            List<TyplmClassificationVO> resultList = typlmClassificationCacheService.queryClassificationByParentID(
                    attributereferenceOid, "N");
            if(CollUtil.isNotEmpty(resultList)){
                List<String> classOidList = new ArrayList<>();
                for(TyplmClassificationVO typlmClassificationVO : resultList){
                    classOidList.add(typlmClassificationVO.getId().toString());
                }
                List<JSONObject> objectList = rtTypeClassMapper.selectPartNumberByIbaAttrOidAndClassOid(
                        String.valueOf(attributeDefaultValueDO.getAttributereferenceoid()),
                        classOidList);
                if (CollUtil.isNotEmpty(objectList)) {
                    throw RTErrorCodeEnum.ENUM_VALUE_NOT_EXIST.getException("存在实例化数据，不允许删除！");
                }
            }else {
                List<JSONObject> objectList = rtTypeClassMapper.selectPartNumberByIbaAttrOidAndClassOid(
                        String.valueOf(attributeDefaultValueDO.getAttributereferenceoid()),
                        Collections.singletonList(attributereferenceOid.toString()));
                if (CollUtil.isNotEmpty(objectList)) {
                    throw RTErrorCodeEnum.ENUM_VALUE_NOT_EXIST.getException("存在实例化数据，不允许删除！");
                }
            }
        }
    }
}
